package com.hbnu.server.ftf.handler;

import com.hbnu.message.FileInfo;
import com.hbnu.message.Response;
import com.hbnu.tools.FileTool;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.serialization.ObjectDecoder;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

import static com.hbnu.tools.FileTool.getUniqueFileName;

@ChannelHandler.Sharable
public class FileServerHandler extends SimpleChannelInboundHandler<Object> {
    private FileInfo fileInfo;
    private FileChannel fileChannel;
    private RandomAccessFile randomAccessFile;

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) throws Exception {
        //System.out.println("开头================================================  "+msg);
        if (msg instanceof FileInfo fileInfo) {
            // 接收到 FileInfo 对象
            System.out.println("接收的对象: " + fileInfo);
            // 准备写入文件
            this.fileInfo=fileInfo;
            //上传请求
            if(fileInfo.isHasFile()){
                //移除对象编码器，会先将剩余ByteBuf处理完,进行回调，再返回
                initializeFileChannel();
                channelHandlerContext.pipeline().remove(ObjectDecoder.class);
            }
        }
        //文件部分
        else if (msg instanceof ByteBuf buf) {
            //读取长度
            int read = fileChannel.write(buf.nioBuffer());
            //读完了
            if(!fileInfo.hasRemaining(read)) {
                System.out.println("文件接收完成！");
                Response response = new Response(true, "上传成功！");
                channelHandlerContext.writeAndFlush(response);
            }
        }
        //其他处理记得传递
        else channelHandlerContext.fireChannelRead(msg);
    }

    private void initializeFileChannel() throws IOException {
        //上传文件重命名
        fileInfo.setsPath(getUniqueFileName(fileInfo.getsPath()));

        // 创建目标文件通道
        randomAccessFile = new RandomAccessFile(fileInfo.getsPath(), "rw");
        randomAccessFile.seek(fileInfo.getStart());
        fileChannel = randomAccessFile.getChannel();
    }



    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // 文件发送完成后关闭连接
        if (fileChannel != null) {
            fileChannel.close();
        }
        if (randomAccessFile != null) {
            randomAccessFile.close();
        }
        ctx.close();
        //System.out.println("连接关闭");
    }
}
